package org.sdp.pearproject.service.custom;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import org.sdp.pearproject.config.ThreadLocalResponse;
import org.sdp.pearproject.dao.domain.*;
import org.sdp.pearproject.dao.mapper.*;
import org.sdp.pearproject.dto.request.*;
import org.sdp.pearproject.dto.response.*;
import org.sdp.pearproject.service.*;
import org.sdp.pearproject.service.impl.*;
import org.sdp.pearproject.utils.DateUtil;
import org.sdp.pearproject.utils.JWTUtil;
import org.sdp.pearproject.utils.JavaBeansUtil;
import org.sdp.pearproject.utils.UUIDUtil;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.util.CollectionUtils;
import org.springframework.util.StringUtils;

import java.lang.reflect.Field;
import java.text.SimpleDateFormat;
import java.util.*;

/**
 * @ClassName: ProjectServiceCustomImpl
 * @Description: 
 * @Author: SDP
 * @Date: 2022-07-08
 * @Version: 1.0
 * Table: pear_project
 * Comment:
 * 项目表
 */
public class ProjectServiceCustomImpl extends ProjectServiceSuperImpl {

    private String[] task_pri = new String[]{"普通", "紧急", "非常紧急"};
    private String[] task_status = new String[] {"未开始", "已完成", "进行中", "挂起", "测试中"};
    private String[] account_status = new String[] {"禁用", "使用中"};
    private String[] menu_inner = new String[] {"导航", "内页"};
    private String[] menu_status = new String[] {"禁用", "使用中"};
    private String[] version_status = new String[] {"未开始", "进行中", "延期发布", "已发布"};

    @Autowired
    ThreadLocalResponse threadLocalResponse;

    @Autowired
    ProjectCollectionService projectCollectionService;

    @Autowired
    ProjectCollectionMapper projectCollectionMapper;

    @Autowired
    ProjectMemberService projectMemberService;

    @Autowired
    ProjectMemberMapper projectMemberMapper;

    @Autowired
    InviteLinkService inviteLinkService;

    @Autowired
    ProjectLogMapper projectLogMapper;

    @Autowired
    TaskMapper taskMapper;

    @Autowired
    InviteLinkMapper inviteLinkMapper;

    @Autowired
    TaskTagService taskTagService;

    @Autowired
    DepartmentService departmentService;

    @Autowired
    DepartmentMapper departmentMapper;

    @Autowired
    MemberMapper memberMapper;

    @Autowired
    EventsService eventsService;

    @Autowired
    MemberAccountMapper memberAccountMapper;

    @Autowired
    EventsMemberService eventsMemberService;

    @Override
    public List<Object> projectCollectCollect(ProjectCollectionAddRequest request) throws Exception {
        super.assertNotNull(request.getProjectCode(), "project_code");
        super.assertNotNull(request.getMemberCode(), "member_code");
        if ("cancel".equals(request.getType())) {
            ProjectCollectionExample example = new ProjectCollectionExample();
            example.createCriteria()
                    .andProjectCodeEqualTo(request.getProjectCode())
                    .andMemberCodeEqualTo(request.getMemberCode());

            projectCollectionMapper.deleteByExample(example);
            threadLocalResponse.set("message", "取消收藏成功");
            return new ArrayList<>();
        } else if ("collect".equals(request.getType())) {
            projectCollectionService.addProjectCollection(request);
            threadLocalResponse.set("message", "加入收藏成功");
            return new ArrayList<>();
        }
        throw createFailException("not implement");
    }

    @Override
    public List<Object> projectMemberInviteMember(ProjectMemberAddRequest request) throws Exception {
        assertNotNull(request.getProjectCode(), "project_code");
        assertNotNull(request.getMemberCode(), "member_code");
        if ("cancel".equals(request.getType())) {
            ProjectMemberExample example = new ProjectMemberExample();
            example.createCriteria()
                    .andProjectCodeEqualTo(request.getProjectCode())
                    .andMemberCodeEqualTo(request.getMemberCode());
            projectMemberMapper.deleteByExample(example);
        } else {
            projectMemberService.addProjectMember(request);
        }

        return new ArrayList<>();
    }

    @Override
    public InviteLinkQueryResponse inviteLinkSave(InviteLinkAddRequest request) throws Exception {
        assertNotNull(request.getSourceCode(), "source_code");
        assertNotNull(request.getInviteType(), "invite_type");

        Date now = new Date();

        {
            InviteLinkExample example = new InviteLinkExample();
            example.createCriteria()
                    .andSourceCodeEqualTo(request.getSourceCode())
                    .andInviteTypeEqualTo(request.getInviteType());

            if ("cancel".equals(request.getType())) {
                inviteLinkMapper.deleteByExample(example);
                return null;
            }
            List<InviteLinkWithBLOBs> list = inviteLinkMapper.selectByExampleWithBLOBs(example);
            for(InviteLinkWithBLOBs item: list) {
                Date overTime = DateUtil.parseDatetime(item.getOverTime());
                if (overTime.getTime() >= now.getTime()) {
                    InviteLinkQueryResponse result = new InviteLinkQueryResponse();
                    BeanUtils.copyProperties(item, result);
                    return result;
                }
            }

            inviteLinkMapper.deleteByExample(example);
        }

        request.setCreateTime(DateUtil.formatDatetime(now));
        request.setOverTime(DateUtil.formatDatetime(DateUtil.add(now, Calendar.HOUR_OF_DAY, 24)));
        request.setCreateBy(request.getMemberCode());
        request.setCode(UUIDUtil.new24());
        Integer id = inviteLinkService.addInviteLink(request);
        if (id > 0) {
            InviteLinkQueryResponse result = new InviteLinkQueryResponse();
            BeanUtils.copyProperties(request, result);
            result.setId(id.intValue());
            return result;
        }
        return null;
    }

    @Override
    public List<ProjectForProjectMemberListForInviteResponse> projectMemberSearchInviteMember(ProjectForProjectMemberListForInviteRequest request) throws Exception {
        List<ProjectForProjectMemberListForInviteResponse> list = projectMemberListForInvite(request);
        if (!StringUtils.hasText(request.getKeyword())) {
            return list;
        }
        List<ProjectForProjectMemberListForInviteResponse> result = new ArrayList<>();
        for (ProjectForProjectMemberListForInviteResponse item: list) {
            if (StringUtils.hasText(item.getName()) && item.getName().contains(request.getKeyword())
                    || StringUtils.hasText(item.getEmail()) && item.getEmail().contains(request.getKeyword())
            ) {
                result.add(item);
            }
        }
        return result;
    }

    @Override
    public List<ProjectForTaskStagesTasksResponse> taskStagesTasks(ProjectForTaskStagesTasksRequest request) throws Exception {
        List<ProjectForTaskStagesTasksResponse> list = super.taskStagesTasks(request);
        Map<String, TaskTagForTagsResponse> tagMap = null;

        for(ProjectForTaskStagesTasksResponse item: list) {
            if (tagMap == null) {
                tagMap = new HashMap<>();
                TaskTagForTagsRequest example = new TaskTagForTagsRequest();
                example.setProjectCode(item.getProjectCode());
                List<TaskTagForTagsResponse> tagList = taskTagService.tags(example);
                for(TaskTagForTagsResponse tag: tagList) {
                    tagMap.put(tag.getCode(), tag);
                }
            }
            if (StringUtils.hasText(item.getExecutorName()) || StringUtils.hasText(item.getExecutorAvatar())) {
                MemberQueryResponse v = new MemberQueryResponse();
                v.setName(item.getExecutorName());
                v.setAvatar(item.getExecutorAvatar());
                item.setExecutor(v);
            }
            if (StringUtils.hasText(item.getTagsCode())) {
                String[] tags = item.getTagsCode().split(",");
                for(String tagInfo: tags) {
                    String[] tagInfos = tagInfo.split(";");
                    TaskTagForTagsResponse tag = tagMap.get(tagInfos[0]);
                    if (tag != null) {
                        TaskToTagForTagsResponse taskToTag = new TaskToTagForTagsResponse();
                        taskToTag.setTagCode(tagInfos[0]);
                        taskToTag.setCode(tagInfos[1]);
                        taskToTag.setCreateTime(tagInfos[2]);
                        taskToTag.setTaskCode(item.getCode());

                        TaskTagForTagsResponse newTag = new TaskTagForTagsResponse();
                        BeanUtils.copyProperties(tag, newTag);
                        taskToTag.setTag(newTag);
                        item.getTags().add(taskToTag);
                    }
                }
            }

            {
                ProjectForIdToNameRequest idToNameRequest = new ProjectForIdToNameRequest();
                idToNameRequest.setType("task_pri");
                idToNameRequest.setId(item.getPri().intValue());
                item.setPriText(this.idToName(idToNameRequest).getName());
            }

            {
                ProjectForIdToNameRequest idToNameRequest = new ProjectForIdToNameRequest();
                idToNameRequest.setType("task_status");
                idToNameRequest.setId(item.getStatus().intValue());
                item.setStatusText(this.idToName(idToNameRequest).getName());
            }

            if (StringUtils.hasText(item.getSubsCode())) {
                item.getChildCount().add(new Integer(item.getSubsCode().split(",").length));
            } else {
                //toJSONString时会输出$ref，原因不明
                item.getChildCount().add(new Integer(0));
            }
            if (StringUtils.hasText(item.getSubsCodeDone())) {
                item.getChildCount().add(new Integer(item.getSubsCodeDone().split(",").length));
            } else {
                //toJSONString时会输出$ref，原因不明
                item.getChildCount().add(new Integer(0));
            }

            //has_un_done是一个冗余的内容
            if (!item.getChildCount().get(0).equals(item.getChildCount().get(1))) {
                item.setHasUnDone(1);
            } else {
                item.setHasUnDone(0);
            }

            if (!StringUtils.hasText(item.getPcode())) {
                item.setParentDone(1);
            }
        }
        return list;
    }

    @Override
    public ProjectForIdToNameResponse idToName(ProjectForIdToNameRequest request) throws Exception {
        ProjectForIdToNameResponse result = new ProjectForIdToNameResponse();
        result.setId(request.getId());
        result.setType(request.getType());
        Field field = JavaBeansUtil.getField(this.getClass(), request.getType());
        if (field == null) {
            return result;
        }
        String[] list = (String[]) field.get(this);
        if (request.getId() >= 0 && request.getId() < list.length) {
            result.setName(list[request.getId().intValue()]);
        }
        return result;
    }

    @Override
    public List<ProjectForProjectResponse> project(ProjectForProjectRequest request) throws Exception {
        List<ProjectForProjectResponse> list = super.project(request);
        for (ProjectForProjectResponse item: list) {
            if (!StringUtils.hasText(item.getOwnerName()) && StringUtils.hasText(item.getOwners())) {
                item.setOwnerName(item.getOwners().split(";")[0]);
            }
        }
        return list;
    }

    @Override
    public List<ProjectForProjectResponse> selfList(ProjectForProjectRequest request) throws Exception {
        request.setSelectBy("self_list");
        if (request.getArchive() == null) {
            request.setArchive(0);
        } else if (request.getArchive() == -1) {
            request.setArchive(null);
        } else if (request.getArchive() == 0 || request.getArchive() == 1){
        } else {
            throw new Exception("not impelemnt");
        }
        return project(request);
    }

    @Override
    public JSONObject notifyNoReads(ProjectForNotifyNoReadsBaseRequest request) throws Exception {
        JSONObject result = new JSONObject();

        JSONObject listObject = new JSONObject();
        listObject.put("notice", new ArrayList<>());
        listObject.put("message", new ArrayList<>());
        listObject.put("task", new ArrayList<>());

        result.put("list", listObject);

        JSONObject totalObject = new JSONObject();
        totalObject.put("notice", new Integer(0));
        totalObject.put("message", new Integer(0));
        totalObject.put("task", new Integer(0));

        result.put("totalSum", totalObject);

        {
            ProjectForNotifyNoReadsBaseRequest example = new ProjectForNotifyNoReadsBaseRequest();
            example.setMemberCode(request.getMemberCode());
            List<ProjectForNotifyNoReadsBaseResponse> list = notifyNoReadsBase(example);
            for(ProjectForNotifyNoReadsBaseResponse item: list) {
                if (result.getJSONObject("list").containsKey(item.getType())) {
                    List<ProjectForNotifyNoReadsBaseResponse> destList = (List<ProjectForNotifyNoReadsBaseResponse>) result.getJSONObject("list").get(item.getType());
                    item.setFrom(null);
                    item.setTo(null);
                    destList.add(item);
                }
            }
        }
        {
            ProjectForNotifyNoReadsCountRequest example = new ProjectForNotifyNoReadsCountRequest();
            example.setMemberCode(request.getMemberCode());
            List<ProjectForNotifyNoReadsCountResponse> list = notifyNoReadsCount(example);
            int total = 0;
            for(ProjectForNotifyNoReadsCountResponse item: list) {
                if (totalObject.containsKey(item.getType())) {
                    totalObject.put(item.getType(), new Integer(item.getCount().intValue()));
                    total += item.getCount().intValue();
                }
            }
            result.put("total", total);
        }
        return result;
    }

    @Override
    public JSONObject account(ProjectForAccountBaseRequest request) throws Exception {
        JSONObject result = new JSONObject();
        Map<String, String> departmentParentMap = new HashMap<>();
        Map<String, DepartmentQueryResponse> departmentMap = new HashMap<>();

        if (!StringUtils.hasText(request.getMemberCodeOri())) {
            request.setMemberCode(null);
            request.setSearchType(0);
        }
        {
            DepartmentQueryRequest example = new DepartmentQueryRequest();
            List<DepartmentQueryResponse> list = departmentService.listDepartment(example);
            for(DepartmentQueryResponse item: list) {
                departmentMap.put(item.getCode(), item);
                if (StringUtils.hasText(item.getPcode())) {
                    departmentParentMap.put(item.getCode(), item.getPcode());
                }
            }
        }
        {
            List<ProjectForAccountBaseResponse> list = accountBase(request);

            for(ProjectForAccountBaseResponse item: list) {
                {
                    ProjectForIdToNameRequest idToNameRequest = new ProjectForIdToNameRequest();
                    idToNameRequest.setType("account_status");
                    idToNameRequest.setId(item.getStatus().intValue());
                    item.setStatusText(idToName(idToNameRequest).getName());
                }

                if (StringUtils.hasText(item.getAuthorize())) {
                    String[] authorizes = item.getAuthorize().split(",");
                    for(String a: authorizes) {
                        item.getAuthorizeArr().add(a);
                    }
                }
                if (!StringUtils.isEmpty(item.getMemberAvatar())) {
                    item.setAvatar(item.getMemberAvatar());
                }
                if (!StringUtils.hasText(item.getDepartments())) {
                    item.setDepartments("");
                } else {
                    String[] departments = item.getDepartments().split(",");
                    Set<String> codeSet = new HashSet<>();
                    for(String code: departments) {
                        codeSet.add(code);
                    }
                    List<String> departmentNameList = new ArrayList<>();
                    String lastCode = "";
                    for(String code: codeSet) {
                        if (departmentParentMap.containsKey(code)) {
                            continue;
                        }
                        lastCode = code;
                        departmentNameList.add(code);
                        codeSet.remove(code);
                        break;
                    }
                    int loop = 30;
                    while(loop > 0 && !CollectionUtils.isEmpty(codeSet)) {
                        loop--;
                        for(String code: departmentParentMap.keySet()) {
                            if (lastCode.equals(departmentParentMap.get(code))) {
                                departmentNameList.add(code);
                                lastCode = code;
                                codeSet.remove(code);
                                break;
                            }
                        }
                    }
                    if (!CollectionUtils.isEmpty(departmentNameList)) {
                        item.setDepartments("");
                        for(String departmentName: departmentNameList) {
                            DepartmentQueryResponse department = departmentMap.get(departmentName);
                            if (department == null) {
                                continue;
                            }
                            if (!"".equals(item.getDepartments())) {
                                item.setDepartments(item.getDepartments() + " - ");
                            }
                            item.setDepartments(item.getDepartments() + department.getName());
                        }
                    }
                }
            }
            result.put("list", list);
        }
        {
            ProjectForAccountBaseRequest example = new ProjectForAccountBaseRequest();
            example.setOrganizationCode(request.getOrganizationCode());
            example.setSearchType(request.getSearchType());
            result.put("total", accountBase(example).size());
        }
        {
            if (request.getPageNo() != null) {
                result.put("page", request.getPageNo());
            }
        }
        {
            ProjectForAccountAuthRequest example = new ProjectForAccountAuthRequest();
            example.setOrganizationCode(request.getOrganizationCode());
            result.put("authList", accountAuth(example));
        }
        return result;
    }

    @Override
    public List<ProjectForProjectTemplateResponse> projectTemplate(ProjectForProjectTemplateRequest request) throws Exception {
        List<ProjectForProjectTemplateResponse> list = super.projectTemplate(request);
        for(ProjectForProjectTemplateResponse item: list) {
            item.setTaskStages(new ArrayList<>());
            if (StringUtils.hasText(item.getTaskStagesInfo())) {
                String[] infos = item.getTaskStagesInfo().split(",");
                Map<String, String> map = new TreeMap<>();
                for(String info: infos) {
                    map.put(info, info.split(";")[1]);
                }
                for(String info: map.keySet()) {
                    TaskStagesTemplateQueryResponse newItem = new TaskStagesTemplateQueryResponse();
                    newItem.setName(map.get(info));
                    item.getTaskStages().add(newItem);
                }
            }
        }
        return list;
    }

    @Override
    public List<ProjectForMenuMenuResponse> menuMenu(ProjectForMenuMenuRequest request) throws Exception {
        List<ProjectForMenuMenuResponse> orilist = super.menuMenu(request);
        Map<String, ProjectForMenuMenuResponse> map = new TreeMap<>();
        List<String> rootList = new ArrayList<>();

        for(ProjectForMenuMenuResponse item: orilist) {
            if (item.getPid() == null) {
                item.setPid(0L);
            }
            {
                ProjectForIdToNameRequest idToNameRequest = new ProjectForIdToNameRequest();
                idToNameRequest.setType("menu_inner");
                idToNameRequest.setId(item.getIsInner() != null && item.getIsInner()? 1 : 0);
                item.setInnerText(idToName(idToNameRequest).getName());
            }
            {
                ProjectForIdToNameRequest idToNameRequest = new ProjectForIdToNameRequest();
                idToNameRequest.setType("menu_status");
                idToNameRequest.setId(item.getStatus().intValue());
                item.setStatusText(idToName(idToNameRequest).getName());
            }
            if (StringUtils.hasText(item.getValues())) {
                item.setFullUrl(item.getFullUrl()+"/"+item.getValues());
            }
            map.put(item.getId(), item);
            if (item.getPid() == 0) {
                rootList.add(item.getId());
            }
        }
        for(ProjectForMenuMenuResponse item: orilist) {
            ProjectForMenuMenuResponse pItem = map.get(item.getPid()+"");
            if (pItem != null) {
                if (pItem.getChildren() == null) {
                    pItem.setChildren(new ArrayList<>());
                }
                pItem.getChildren().add(item);
            }
        }
        List<ProjectForMenuMenuResponse> list = new ArrayList<>();
        for(String id: rootList) {
            list.add(map.get(id));
        }
        return list;
    }

    @Override
    public JSONObject node(BaseRequest request) throws Exception {
        throw createFailException("not implement");
    }

    @Override
    public List<ProjectForNotifyResponse> notify(ProjectForNotifyRequest request) throws Exception {
        if (StringUtils.hasText(request.getDate())) {
            String[] ss = request.getDate().split("~");
            request.setCreateTimeGe(DateUtil.parseDate(ss[0]));
            request.setCreateTimeLt(DateUtil.parseDate(ss[1]));
            request.getCreateTimeLt().setTime(request.getCreateTimeLt().getTime() + 24*60*60*1000);
        }
        return super.notify(request);
    }

    @Override
    public List<ProjectForMenuMenuResponse> index(ProjectForMenuMenuRequest request) throws Exception {
        return menuMenu(request);
    }

    @Override
    public JSONObject indexSystemConfig(BaseRequest request) throws Exception {
        ProjectForIndexSystemConfigBaseRequest example = new ProjectForIndexSystemConfigBaseRequest();
        example.setIdLe(7);
        List<ProjectForIndexSystemConfigBaseResponse> list = indexSystemConfigBase(example);
        JSONObject result = new JSONObject();
        for(ProjectForIndexSystemConfigBaseResponse item: list) {
            if (StringUtils.hasText(item.getValue())) {
                result.put(item.getName(), item.getValue());
            }
        }
        return result;
    }

    @Override
    public JSONObject login(ProjectForLoginRequest request) throws Exception {
        ProjectForMemberBaseResponse member;
        {
            ProjectForMemberBaseRequest example = new ProjectForMemberBaseRequest();
            example.setAccount(request.getAccount());
            List<ProjectForMemberBaseResponse> list = memberBase(example);
            if (CollectionUtils.isEmpty(list)) {
                throw new Exception("未找到用户");
            }

            member = list.get(0);
            Member memberRecord = memberMapper.selectByCode(member.getCode());
            if (!StringUtils.hasText(memberRecord.getPassword())) {
                throw new Exception("用户未设置密码");
            }
            if (!memberRecord.getPassword().equals(request.getPassword())) {
                throw new Exception("密码不正确");
            }
        }

        String token = JWTUtil.createToken(member.getCode());

        JSONObject result = new JSONObject();

        String organization_code = null;
        {
            ProjectForAccountBaseRequest example = new ProjectForAccountBaseRequest();
            example.setMemberCode(member.getCode());
            List<ProjectForAccountBaseResponse> list = accountBase(example);
            if (CollectionUtils.isEmpty(list)) {
                throw new Exception("缺少account信息");
            }
            if (!StringUtils.hasText(list.get(0).getOrganizationCode())) {
                throw new Exception("缺少organization_code");
            }
            organization_code = list.get(0).getOrganizationCode();

            member.setAccountId(list.get(0).getId());
            member.setOrganizationCode(organization_code);
            if (StringUtils.hasText(list.get(0).getDepartments())) {
                String departmentCode = list.get(0).getDepartments().split(",")[0];
                Department department = departmentMapper.selectByCode(departmentCode);
                if (department != null) {
                    member.setDepartment(department.getName());
                }
            }
            member.setAuthorize(list.get(0).getAuthorize());
            member.setPosition(list.get(0).getPosition());
            //TODO: member.isOwner为什么是Integer类型，而不是Byte类型？
            member.setIsOwner(list.get(0).getIsOwner() == null ? null : list.get(0).getIsOwner().intValue());
        }

        {
            ProjectForNodeAuthBaseRequest example = new ProjectForNodeAuthBaseRequest();
            example.setMemberCode(member.getCode());
            List<ProjectForNodeAuthBaseResponse> list = nodeAuthBase(example);
            member.setNodes(new ArrayList<>());
            for(ProjectForNodeAuthBaseResponse item: list) {
                member.getNodes().add(item.getNode());
            }
        }

        result.put("member", member);

        {
            JSONObject tokenList = new JSONObject();
            tokenList.put("accessToken", token);
            tokenList.put("refreshToken", token);
            tokenList.put("tokenType", "bearer");
            tokenList.put("accessTokenExp", JWTUtil.getExp(token).getTime() / 1000);

            result.put("tokenList", tokenList);
        }

        {
            ProjectForOrganizationGetOrgListRequest example = new ProjectForOrganizationGetOrgListRequest();
            example.setMemberCode(member.getCode());
            List<ProjectForOrganizationGetOrgListResponse> list = organizationGetOrgList(example);

            result.put("organizationList", list);
        }

        threadLocalResponse.set("code", 200);
        return result;
    }

    @Override
    public JSONObject eventsGetEventsListByCalendar(ProjectForEventsGetEventsListByCalendarRequest request) throws Exception {
        JSONObject result = new JSONObject();

        Date now = new Date();
        Date tsp_begin = DateUtil.addMonths(now, -1);
        tsp_begin = DateUtil.parseDate(DateUtil.formatDate(tsp_begin).substring(0, 8) + "01");
        Date tsp_end = DateUtil.addMonths(now, 2);
        tsp_end = DateUtil.parseDate(DateUtil.formatDate(tsp_end).substring(0, 8) + "02");

        Map<String, EventsForEventsResponse> eventsMap = new HashMap<>();

        Set<String> memberCodeSet = new HashSet<>();

        for(String memberCode: request.getMemberCodes())
        {
            memberCodeSet.add(memberCode);

            EventsForEventsRequest example = new EventsForEventsRequest();
            example.setBeginTimeGe(tsp_begin);
            example.setEndTimeLt(tsp_end);
            example.setMemberCode(memberCode);
            List<EventsForEventsResponse> list = eventsService.events(example);
            for(EventsForEventsResponse item: list) {
                eventsMap.put(item.getCode(), item);
            }
        }

        Map<String, Map<String, EventsForEventsMemberResponse>> eventsMemberMap = new HashMap<>();
        for(String memberCode: request.getMemberCodes())
        {
            EventsForEventsMemberRequest example = new EventsForEventsMemberRequest();
            example.setMemberCode(memberCode);
            example.setBeginTimeGe(tsp_begin);
            example.setEndTimeLt(tsp_end);
            List<EventsForEventsMemberResponse> list = eventsService.eventsMember(example);
            for(EventsForEventsMemberResponse item: list) {
                EventsForEventsResponse event = eventsMap.get(item.getEventsCode());
                if (event == null) {
                    continue;
                }
                if (!eventsMemberMap.containsKey(item.getEventsCode())) {
                    eventsMemberMap.put(item.getEventsCode(), new HashMap<>());
                }
                eventsMemberMap.get(item.getEventsCode()).put(item.getMemberCode(), item);
            }
        }

        List<EventsForEventsResponse> eventsList = new ArrayList<>();
        Map<String, List<EventsForEventsResponse>> dateMap = new HashMap<>();
        for(String eventCode: eventsMap.keySet()) {
            EventsForEventsResponse event = eventsMap.get(eventCode);
            Map<String, EventsForEventsMemberResponse> map = eventsMemberMap.get(eventCode);
            if (map == null) {
                continue;
            }
            Map<String, EventsForEventsMemberResponse> members = eventsMemberMap.get(event.getCode());
            if (members == null) {
                continue;
            }

            event.setMemberList(new ArrayList<>());

            boolean found = false;
            for(String memberCode: members.keySet()) {
                if (memberCodeSet.contains(memberCode)) {
                    found = true;
                }
                EventsForEventsMemberResponse member = members.get(memberCode);
                JSONObject memberJson = JSON.parseObject(JSON.toJSONString(member));

                JSONObject memberInfoJson = new JSONObject();
                memberJson.put("memberInfo", memberInfoJson);
                memberInfoJson.put("name", member.getMemberName());
                memberInfoJson.put("avatar", member.getMemberAvatar());

                event.getMemberList().add(memberJson);
            }
            if (!found) {
                continue;
            }

            String date = event.getBeginTime().split(" ")[0];
            eventsList.add(eventsMap.get(eventCode));
            if (!dateMap.containsKey(date)) {
                dateMap.put(date, new ArrayList<>());
            }
            dateMap.get(date).add(event);
        }
        Map<String, List<EventsForEventsResponse>> resultList = new TreeMap<>();
        List<String> rangeList = new ArrayList<>();
        while(tsp_begin.before(tsp_end)) {
            String date = DateUtil.formatDate(tsp_begin);
            rangeList.add(date);
            if (dateMap.containsKey(date)) {
                resultList.put(date, dateMap.get(date));
            } else {
                resultList.put(date, new ArrayList<>());
            }
            tsp_begin.setTime(tsp_begin.getTime() + 24*60*60*1000);
        }
        result.put("list", resultList);
        result.put("dateRange", rangeList);

        threadLocalResponse.set("code", 200);
        return result;
    }

    @Override
    public List<ProjectForAccountBaseResponse> accountAllList(BaseRequest request) throws Exception {
        ProjectForAccountBaseRequest example = new ProjectForAccountBaseRequest();
        BeanUtils.copyProperties(request, example);
        example.setSearchType(0);

        //TODO: 请求传了一个page_size，但是还直接返回List？
        threadLocalResponse.set("without_total", 1);
        List<ProjectForAccountBaseResponse> list = accountBase(example);
        for(ProjectForAccountBaseResponse item: list) {
            if (!StringUtils.hasText(item.getAvatar())) {
                item.setAvatar(item.getMemberAvatar());
            }
        }
        return list;
    }

    @Override
    public List<Object> accountResume(ProjectForAccountResumeRequest request) throws Exception {
        MemberAccountExample example = new MemberAccountExample();
        example.createCriteria().andCodeEqualTo(request.getAccountCode());
        MemberAccountWithBLOBs record = new MemberAccountWithBLOBs();
        record.setStatus((byte)1);
        memberAccountMapper.updateByExampleSelective(record, example);
        return new ArrayList<>();
    }

    @Override
    public List<Object> accountForbid(ProjectForAccountForbidRequest request) throws Exception {
        MemberAccountExample example = new MemberAccountExample();
        example.createCriteria().andCodeEqualTo(request.getAccountCode());
        MemberAccountWithBLOBs record = new MemberAccountWithBLOBs();
        record.setStatus((byte)0);
        memberAccountMapper.updateByExampleSelective(record, example);
        return new ArrayList<>();
    }

    @Override
    public List<ProjectForProjectVersionResponse> projectVersion(ProjectForProjectVersionRequest request) throws Exception {
        List<ProjectForProjectVersionResponse> list = super.projectVersion(request);
        for(ProjectForProjectVersionResponse item: list) {
            {
                ProjectForIdToNameRequest idToNameRequest = new ProjectForIdToNameRequest();
                idToNameRequest.setType("version_status");
                idToNameRequest.setId(item.getStatus().intValue());
                item.setStatusText(idToName(idToNameRequest).getName());
            }
        }
        return list;
    }

    @Override
    public List<ProjectForTaskSelfListResponse> taskSelfList(ProjectForTaskSelfListRequest request) throws Exception {
        List<ProjectForTaskSelfListResponse> list = super.taskSelfList(request);
        for(ProjectForTaskSelfListResponse item: list) {
            item.getExecutor().put("name", item.getExecutorName());
            item.getExecutor().put("avatar", item.getExecutorAvatar());

            item.getProjectInfo().put("name", item.getProjectName());
            item.getProjectInfo().put("code", item.getProjectCode());

            {
                ProjectForIdToNameRequest idToNameRequest = new ProjectForIdToNameRequest();
                idToNameRequest.setType("task_pri");
                idToNameRequest.setId(item.getPri().intValue());
                item.setPriText(this.idToName(idToNameRequest).getName());
            }

            if (StringUtils.hasText(item.getSubsCode())) {
                item.getChildCount().add(new Integer(item.getSubsCode().split(",").length));
            } else {
                //toJSONString时会输出$ref，原因不明
                item.getChildCount().add(new Integer(0));
            }
            if (StringUtils.hasText(item.getSubsCodeDone())) {
                item.getChildCount().add(new Integer(item.getSubsCodeDone().split(",").length));
            } else {
                //toJSONString时会输出$ref，原因不明
                item.getChildCount().add(new Integer(0));
            }

            //has_un_done是一个冗余的内容
            if (!item.getChildCount().get(0).equals(item.getChildCount().get(1))) {
                item.setHasUnDone(1);
            } else {
                item.setHasUnDone(0);
            }

            if (!StringUtils.hasText(item.getPcode())) {
                item.setParentDone(1);
            }
        }

        return list;
    }

    @Override
    public List<Object> eventsSave(EventsAddRequest request) throws Exception {
        String code = UUIDUtil.new24();
        {
            EventsAddRequest example = new EventsAddRequest();
            BeanUtils.copyProperties(request, example);
            example.setCode(code);
            //example.setOrganizationCode(request.getOrganizationCode());
            example.setCreatedBy(request.getMemberCodeAuth());
            eventsService.addEvents(example);
        }
        if (CollectionUtils.isEmpty(request.getMemberList())) {
            request.setMemberList(new ArrayList<>());
            request.getMemberList().add(request.getMemberCodeAuth());
        }

        for(String memberCode: request.getMemberList()) {
            EventsMemberAddRequest example = new EventsMemberAddRequest();
            example.setEventsCode(code);
            example.setMemberCode(memberCode);
            if (memberCode.equals(request.getMemberCodeAuth())) {
                example.setIsOwner(1);
                example.setStatus((byte)1);
            } else {
                example.setStatus((byte)0);
            }
            example.setProjectCode(request.getProjectCode());
            example.setJoinTime(DateUtil.formatDatetime(new Date()));
            example.setProjectCode(request.getProjectCode());
            eventsMemberService.addEventsMember(example);
        }
        return new ArrayList<>();
    }

    @Override
    public List<Object> loginOut(BaseRequest request) throws Exception {
        //TODO 前端传送了Cookie，需要处理清理Cookie信息，以及令该Cookie对应的JWT失效
        return new ArrayList<>();
    }

    @Override
    public List<ProjectForTaskLogResponse> taskLog(ProjectForTaskLogRequest request) throws Exception {
        List<ProjectForTaskLogResponse> list = super.taskLog(request);
        for(ProjectForTaskLogResponse item: list) {
            item.setMember(new JSONObject());
            item.getMember().put("id", item.getMemberId());
            item.getMember().put("avatar", item.getMemberAvatar());
            item.getMember().put("code", item.getMemberCode());
            item.getMember().put("name", item.getMemberName());
        }
        Collections.sort(list, new Comparator<ProjectForTaskLogResponse>() {
            @Override
            public int compare(ProjectForTaskLogResponse o1, ProjectForTaskLogResponse o2) {
                return o1.getId() - o2.getId();
            }
        });
        return list;
    }

    @Override
    public Boolean taskCreateComment(ProjectForTaskCreateCommentParamRequest request) throws Exception {

        SimpleDateFormat fullDateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");

        ProjectLogWithBLOBs record = new ProjectLogWithBLOBs();
        record.setCode(UUIDUtil.new24());
        record.setMemberCode(request.getMemberCodeAuth());
        record.setContent(request.getComment());
        record.setRemark(request.getComment());
        record.setType("comment");
        record.setCreateTime(fullDateFormat.format(new Date()));
        record.setSourceCode(request.getTaskCode());
        record.setActionType("task");
        record.setIsComment((byte)1);
        record.setIsRobot((byte)0);
        record.setToMemberCode("");
        record.setIcon("file-text");
        Task task = taskMapper.selectByCode(request.getTaskCode());
        record.setProjectCode(task.getProjectCode());
        projectLogMapper.insertSelective(record);
        return true;
    }
}
